//导入axios
import axios from 'axios'
import type {
  AxiosInstance,
  AxiosResponse,
  InternalAxiosRequestConfig,
  AxiosRequestConfig,
  AxiosError,
} from 'axios'
//element-plus 弹窗
import { ElMessage } from 'element-plus'
//导入路由对象
import router from '@/router/index'
//loading遮罩层
import { ElLoading } from 'element-plus'
//请求响应数据结构
import type { R } from '@/model/BaseModel'
//导入全局token管理
import { useUserInfoStore } from '@/stores/UserStores'

// 当前请求的个数
let requestCount = 0
// 加载效果的实例
let loadingInstance: any = null
//打开遮罩层
const openLoading = () => {
  if (requestCount == 0) {
    loadingInstance = ElLoading.service({
      lock: true,
      text: 'Loading',
      background: 'rgba(0, 0, 0, 0.7)',
    })
  }
  requestCount++
}
//关闭遮罩层
const closeLoading = () => {
  requestCount--
  if (requestCount <= 0 && loadingInstance) {
    requestCount = 0
    loadingInstance.close()
  }
}
//根路径
export const config = {
  baseURL: import.meta.env.VITE_API_BASE_URL,

  timeout: 30000,
  headers: {
    'Content-Type': 'application/json',
  },
}

//请求类
export class HttpClient {
  // axios的实例
  private instance: AxiosInstance
  // 初始化的作用
  constructor(configs: AxiosRequestConfig) {
    // 创建axios的实例
    this.instance = axios.create(configs)
    // 配置拦截器
    this.interceptors()
  }
  private interceptors() {
    // 拦截请求
    this.instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
      const token = useUserInfoStore().getToken
      if (token) {
        config.headers.authorization = token
      }
      openLoading()
      return config
    }),
      (error: any) => {
        error.data = {}
        error.data.message = '服务器异常请联系管理员'
        return error
      }
    // 拦截响应
    this.instance.interceptors.response.use(
      (res: AxiosResponse) => {
        closeLoading()
        // 这里面可以做一些接口返回状态的判断
        const token = res.headers.authorization
        if (token) {
          useUserInfoStore().setToken(token)
        }
        //执行成功返回状态码以2开头，主要作用对于修改成功、新增成功等操作的消息提醒
        if (res.data.success) {
          if (res.data.code != 200) {
            ElMessage.success(res.data.message)
          }
          return Promise.resolve(res.data)
        } else {
          //执行异常的消息提醒
          ElMessage.error(res.data.message)
          // HttpBase.errorHandle(res.data.code)
          return Promise.reject(res.data.message || '接口报错')
        }
      },
      (error) => {
        closeLoading()
        if (error.code === 'ERR_NETWORK') {
          ElMessage.error('请检查您的网络')
        } else {
          const status = error.response.status
          HttpClient.errorHandle(status)
        }

        return Promise.reject(error)
      },
    )
  }
  // 下面是对几个请求方式的封装
  // post
  protected post<T = R>(url: string, data?: object): Promise<T> {
    return this.instance.post(url, data)
  }
  //put
  protected put<T = R>(url: string, data?: object): Promise<T> {
    return this.instance.put(url, data)
  }
  // get
  protected get<T = R>(url: string, params?: object): Promise<T> {
    return this.instance.get(url, { params })
  }
  // delete
  protected delete<T = R>(url: string): Promise<T> {
    return this.instance.delete(url)
  }
  // 图片上传
  protected upload<T = R>(url: string, params?: object): Promise<T> {
    return this.instance.post(url, params, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    })
  }
  private static errorHandle(status: number) {
    // 状态码判断
    switch (status) {
      case 404:
        router.push('/404')
        break
      case 10004:
        localStorage.clear()
        router.push('/login')
        break
      case 10005:
        localStorage.clear()
        router.push('/login')
        break
    }
  }
}
